package com.uniview.service;

import com.uniview.eumn.CommonEnum;
import com.uniview.exception.CommonException;
import com.uniview.utils.CalendarUtils;
import com.uniview.utils.EncryptUtils;
import com.uniview.utils.StringUtils;
import com.uniview.utils.TransSeqGenerator;
import com.uniview.orm.daoX.AuthClientDetailsMapper;
import com.uniview.orm.daoX.SysUserMapper;
import com.uniview.orm.model.AuthClientDetails;
import com.uniview.orm.model.SysUser;
import com.uniview.orm.model.SysUserExample;
import com.uniview.util.ThreadUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @Author lux
 * @date: 2019/11/26
 * @desc: 用户服务，直接访问本系统服务
 */
@Service
public class UserService {
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private AuthClientDetailsMapper authClientDetailsMapper;
    /**
     * @desc 用户注册
     * @param userName 用户名
     * @param password 用户密码
     */
    public void register(String userName,String password){
        //校验userName全局不能重复
        SysUserExample sysUserExample = new SysUserExample();
        sysUserExample.createCriteria().andUsernameEqualTo(userName);
        List<SysUser> sysUserList =  sysUserMapper.selectByExample(sysUserExample);
        if(!sysUserList.isEmpty()){
            //校验和写操作不能分离 todo
            throw new CommonException(CommonEnum.USERNAME_REPEAT_CODE, CommonEnum.USERNAME_REPEAT_MSG);
        }
        SysUser sysUser = new SysUser();
        sysUser.setId(TransSeqGenerator.getUserId());
        sysUser.setUsername(userName);
        sysUser.setPassword(EncryptUtils.md5Hex(password));
        sysUserMapper.insertSelective(sysUser);
    }
    /**
     * @desc 用户登录
     * @param userName 用户名
     * @param password 用户密码
     * @return map:用户信息
     */
    public Map<String,Object> login(String userName, String password){
        //通过用户名获取userInfo
        SysUserExample sysUserExample = new SysUserExample();
        sysUserExample.createCriteria().andUsernameEqualTo(userName);
        List<SysUser> userList = sysUserMapper.selectByExample(sysUserExample);
        if(userList.size()!=1){
            throw new CommonException(CommonEnum.USER_ABNORMAL_CODE, CommonEnum.USER_ABNORMAL_MSG);
        }
        SysUser sysUser = userList.get(0);
        //获取用户密码
        String pwdDb=sysUser.getPassword();
        String encodePwd=EncryptUtils.md5Hex(password);
        //校验用户名和密码
        if(!pwdDb.equals(encodePwd)){
            throw new CommonException(CommonEnum.PWD_ERROR_CODE, CommonEnum.PWD_ERROR_MSG);
        }
        //返回访问token,怎么防止token重放攻击
        String token = UUID.randomUUID().toString().replace("_","");
        redisTemplate.opsForValue().set(token,sysUser,5, TimeUnit.MINUTES);
        Map<String,Object> tokenMap = new HashMap<>();
        tokenMap.put("token",token);
        tokenMap.put("userId",sysUser.getId());
        tokenMap.put("userName",sysUser.getUsername());
        return tokenMap;
    }

    /**
     * @desc 申请客户端注册
     * @param clientName client名字
     * @param redirectUri 重定向uri
     */
    public AuthClientDetails register(String clientName, String redirectUri, String grantTypes, String scopes){
        SysUser sysUser = ThreadUtils.getUserHolder();
        //校验客户端名称和回调地址不能为空
        if(StringUtils.checkIsStrNull(clientName)||StringUtils.checkIsStrNull(redirectUri)){
            throw new CommonException(CommonEnum.CLIENT_ERROR_CODE, CommonEnum.CLIENT_ERROR_MSG);
        }
        //生成全局唯一的clientId
        String clientId = UUID.randomUUID().toString().replace("_","");
        //生成随机的clientSecret
        String clientSecret = UUID.randomUUID().toString().replace("_","");
        AuthClientDetails authClientDetails = new AuthClientDetails();
        authClientDetails.setId(TransSeqGenerator.getId());
        authClientDetails.setClientId(clientId);
        authClientDetails.setClientName(clientName);
        authClientDetails.setClientSecret(EncryptUtils.md5Hex(clientSecret));
        authClientDetails.setCreateTime(CalendarUtils.getDateTime());
        authClientDetails.setCreateUser(sysUser.getId());
        authClientDetails.setGrantTypes(grantTypes);
        authClientDetails.setUpdateTime(CalendarUtils.getDateTime());
        authClientDetails.setUpdateUser(sysUser.getId());
        authClientDetails.setClientScope(scopes);
        authClientDetailsMapper.insertSelective(authClientDetails);
        return authClientDetails;
    }
}
